package GUI;

import game.GameBase;
import game.Loadable;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Vector;

import util.INIGroup;

public class ButtonSkin implements Loadable
{
	public static final int CENTER = 0;
	public static final int LEFT = 1;
	public static final int RIGHT = 2;
	public final static int UL = 0, U = 1, UR = 2, L = 3, C = 4, R = 5, DL = 6, D = 7, DR = 8;
	private static HashMap<String, ButtonSkin> buttons = new HashMap<String, ButtonSkin>();
	private static Vector<ButtonSkin> blist = new Vector<ButtonSkin>();
	
	private String tag = "", imgNormal = "", imgPushed = "";
	private int sliceSize = 0;
	
	private BufferedImage slices[][] = null;
	
	private ButtonSkin()
	{
	
	}
	
	public static BufferedImage[] cutImage(Image img, int w, int h)
	{
		BufferedImage temp[] = new BufferedImage[9];
		
		for(int x = 0; x < 3; ++x)
		{
			for(int y = 0; y < 3; ++y)
			{
				BufferedImage b = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
				Graphics2D g = b.createGraphics();
				
				while(!g.drawImage(img, 0, 0, w, h, x * w, y * h, x * w + w, y * h + h, null));
				
				temp[x + y * 3] = b;
			}
		}
		return temp;
	}

	@Override
	public boolean loadFromFile(INIGroup grupa)
	{
		tag = grupa.getString("Tag", "button");
		sliceSize = grupa.getInteger("SliceSize", 1);
		imgNormal = grupa.getString("Normal", "");
		imgPushed = grupa.getString("Pushed", "");
		return true;
	}

	@Override
	public String getTag()
	{
		return tag;
	}

	@Override
	public void init()
	{
		BufferedImage img1 = ImageStorage.getImage(imgNormal),
					  img2 = ImageStorage.getImage(imgPushed);
		
		slices = new BufferedImage[2][];
		if(img1 != null)
			slices[0] = cutImage(img1, sliceSize, sliceSize);
		
		if(img2 != null)
			slices[1] = cutImage(img2, sliceSize, sliceSize);
	}
	
	public void drawSimpleButton(Graphics2D g, String text, int x, int y, int w, int h, boolean pushed)
	{
		drawTo(g, x, y, w, h, pushed);
		if(pushed)
		{
			ButtonSkin.drawText(g, text, Color.white, x + shadowOffset, y + shadowOffset, w, h,
					ButtonSkin.CENTER, false);
		}
		else
		{
			ButtonSkin.drawText(g, text, Color.white, x, y, w, h,
					ButtonSkin.CENTER, true);
		}
	}
	
	public void drawTo(Graphics2D g, int x, int y, int w, int h, boolean pushed) {
		if(w <= 0 || h <= 0) return;
 		
		Dimension dim = new Dimension(sliceSize, sliceSize);

		
		g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g.setRenderingHint(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		
		int i = pushed ? 0 : 1;
		// Corners
		BufferedImage cimg = slices[i][UL];
		g.translate(x, y);
		g.drawImage(cimg, 0, 0, dim.width, dim.height, 0, 0, dim.width,
				dim.height, null);

		cimg = slices[i][UR];
		g.drawImage(cimg, w - dim.width, 0, w, dim.height, 0, 0, dim.width,
				dim.height, null);

		cimg = slices[i][DL];
		g.drawImage(cimg, 0, h - dim.width, dim.width, h, 0, 0, dim.width,
				dim.height, null);

		cimg = slices[i][DR];
		g.drawImage(cimg, w - dim.width, h - dim.height, w, h, 0, 0, dim.width,
				dim.height, null);

		// Sides
		cimg = slices[i][U];
		g.drawImage(cimg, dim.width, 0, w - dim.width, dim.height, 0, 0,
			dim.width, dim.height, null);

		cimg = slices[i][D];
		g.drawImage(cimg, dim.width, h - dim.height, w - dim.width, h, 0, 0,
			dim.width, dim.height, null);

		cimg = slices[i][L];
		g.drawImage(cimg, 0, dim.height, dim.width, h - dim.height, 0, 0,
			dim.width, dim.height, null);

		cimg = slices[i][R];
		g.drawImage(cimg, w - dim.width, dim.height, w, h - dim.height, 0, 0,
			dim.width, dim.height, null);

		// Center
		cimg = slices[i][C];
		g.drawImage(cimg, dim.width, dim.height, w - dim.width, h - dim.height,
			0, 0, dim.width, dim.height, null);
		g.translate(-x, -y);
	}
	
	public static void loadToBase(INIGroup g)
	{
		ButtonSkin bs = new ButtonSkin();
		bs.loadFromFile(g);
		buttons.put(bs.getTag(), bs);
		blist.add(bs);
	}
	
	public static void initButtons()
	{
		for(ButtonSkin bs : blist)
			bs.init();
	}
	
	public static ButtonSkin getButtonByTag(String tag)
	{
		GameBase.get();
		return buttons.get(tag);
	}
	
	private static final Color shadowColor = Color.black;
	private static final int shadowOffset = 1;
	
	public static void drawText(Graphics2D g, String text, Color textColor, int posX, int posY, int w, int h, int alignment, boolean doShadow) {
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
	
		//g.setFont(FontManager.get().getServiceProduct("menuFont").deriveFont(fontSize));
		FontMetrics fm = g.getFontMetrics();
		Rectangle2D lm = fm.getStringBounds(text, g);
		
		int x = 0, y = 0;
		
		Rectangle bounds = new Rectangle(posX, posY, w, h);
		Insets insets = new Insets(0, 0, 0, 0);
		y = insets.top + (int) ((bounds.getHeight() - insets.top - insets.bottom) / 2) + g.getFont().getSize() / 3;
		
		switch(alignment)
		{
			case LEFT: x = bounds.x + insets.left; break;
			case RIGHT: x = (int) (bounds.x + bounds.width - lm.getWidth()) - insets.right; break;
			default: x = (int) ((bounds.getWidth() - insets.left - insets.right) / 2 - lm.getWidth() / 2); break;
		}

		if(doShadow)
		{
			g.setColor(shadowColor);
			g.drawString(text, posX + x + shadowOffset, posY + y + shadowOffset);
		}
		
		g.setColor(textColor);
		g.drawString(text, posX + x, posY + y);
	}
}
